package labox.innovation.gameserver.idfactory;

import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import labox.innovation.config.Config;

/**
 * GUID工厂类
 *
 * @author squll 
 */

public class GUIDFactory extends IdFactory {

	private static Logger _log = LoggerFactory.getLogger(GUIDFactory.class.getName());

	private static class TimeIDServer extends Thread {

		private volatile long timeFlag;

		private AtomicLong timeCounter = new AtomicLong();

		private static final long SERVER_ID = (Config.SERVER_ID & 0xffL) << 36;

		private static final long TENMIN = 10 * 60 * 1000L;

		public TimeIDServer() {
			Calendar c = Calendar.getInstance();
			Date cur = c.getTime();
			//Calendar中月从0开始，所以1月是0
			c.set(2010, 0, 1, 0, 0, 0);
			Date old = c.getTime();
			timeFlag = (cur.getTime() - old.getTime()) / TENMIN;
			timeCounter.set(0);
			setDaemon(true);
			start();
		}

		public void run() {
			try {
				Thread.sleep(TENMIN);
			} catch (Exception e) {
				// TODO: handle exception
			}
			timeFlag++;
			timeCounter.set(0);
		}

		/**
		 * 获得时间标识信息<br>
		 * T：时间标志<br>
		 * A：服务器ID<br>
		 * C：ID申请计数器<br>
		 * 
		 * 0x TTTTT  AA    C    OO  RR  IIII <br>
		 *    -----  --   ---   ------------ <br>
		 *    20bit  8bit 4bit      32bit <br>
		 * @return 时间标识信息
		 */
		public long getTimeFlag() {
			return (timeFlag << 44) | SERVER_ID | (timeCounter.getAndIncrement() << 32);
		}

	}

	private TimeIDServer TimeIDServer;

	private AtomicLong idCounter = new AtomicLong();

	private long timeFlag;

	protected GUIDFactory() {
		super();
		TimeIDServer = new TimeIDServer();
		idCounter.set(0);
		timeFlag = TimeIDServer.getTimeFlag();
		_initialized = true;
		_log.info("GUIDFactory: init successful",Config.SERVER_ID);
	}

	/**
	 * 
	 * @see labox.innovation.gameserver.idfactory.IdFactory#releaseId(int)
	 */

	public void releaseId(int objectID) {
	}

	/**
	 * 
	 * @see labox.innovation.gameserver.idfactory.IdFactory#getNextId()
	 */

	public int getNextId() {
		return 0;
	}

	/**
	 * 
	 * @see labox.innovation.gameserver.idfactory.IdFactory#size()
	 */

	public int size() {
		return 0;
	}

	/**
	 * 获得ID标识信息
	 * T：时间标志
	 * A：服务器ID
	 * C：ID申请计数器
	 * O: 对象类型
	 * R：预留位
	 * I：实际序号计数器
	 * 
	 * 0x TTTTT  AA    C     OO    RR    IIII
	 *    -----  --   ---    --    --    ----
	 *    20bit  8bit 4bit  8bit  8bit  16bit
	 * @return 时间标识信息
	 */

	public long getNextId(int type) {

		long val = timeFlag | type << 24 | idCounter.getAndIncrement();

		synchronized (idCounter) {
			if (idCounter.get() > 65535L) {
				timeFlag = TimeIDServer.getTimeFlag();
				idCounter.set(0);
			}
		}

		return val;
	}

	public static void main(String[] s) {
		GUIDFactory g = new GUIDFactory();
		for (int i = -1; ++i < 70000;) {
			System.out.println(Long.toBinaryString(g.getNextId(0)));
		}
	}
}
